home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / matrix.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  7KB  |  343 lines

  1.  
  2. #include <stdio.h>
  3. #include "vogl.h"
  4.  
  5. static    Mstack    *msfree =  (Mstack *) NULL;
  6. void _mapmsave();
  7.  
  8. /*
  9.  * copyvector
  10.  *
  11.  * Copy the 4 vector b to a.
  12.  *
  13.  */
  14. void copyvector(
  15.   register Vector a,
  16.   register Vector b)
  17. {
  18. a[0] = b[0];
  19. a[1] = b[1];
  20. a[2] = b[2];
  21. a[3] = b[3];
  22. }
  23.  
  24. /* ------------------------------------------------------------------------ */
  25.  
  26. /*
  27.  * copymatrix
  28.  *
  29.  * Copy the  4 x 4 matrix b to the 4 x 4 matrix a
  30.  *
  31.  */
  32. void copymatrix(
  33.   register Matrix a,
  34.   register Matrix b)
  35. {
  36. register int    i;
  37. register float    *pa, *pb;
  38.  
  39. pa = (float *)a;
  40. pb = (float *)b;
  41. for(i = 0; i < 16; i++)
  42. *(pa++) = *(pb++);
  43. }
  44.  
  45. /* ------------------------------------------------------------------------ */
  46.  
  47. /*
  48.  * copytranspose
  49.  *
  50.  *    copy the transpose of the 4 x 4 matrix b to the 4 x 4 matrix a.
  51.  */
  52. void copytranspose(
  53.   register Matrix a,
  54.   register Matrix b)
  55. {
  56. register int    i, j;
  57.  
  58. for(i = 0; i < 4; i++)
  59. for(j = 0; j < 4; j++)
  60. a[i][j] = b[j][i];
  61. }
  62.  
  63. /* ------------------------------------------------------------------------ */
  64.  
  65. /*
  66.  * Retreive the top matrix on the stack and place it in m
  67.  */
  68. void getmatrix(Matrix m)
  69. {
  70. copymatrix(m, vdevice.transmat->m);
  71. }
  72.  
  73. /* ------------------------------------------------------------------------ */
  74.  
  75. /*
  76.  * pushmatrix
  77.  *
  78.  * Push the top matrix of the stack down, placing a copy
  79.  * of it on the top of the stack.
  80.  *
  81.  */
  82. void pushmatrix(void)
  83. {
  84. Mstack    *tmpmat;
  85. Token    *p;
  86.  
  87. if (vdevice.inobject) {
  88.     p = newtokens(1);
  89.  
  90.     p->i = PUSHMATRIX;
  91.  
  92.     return;
  93.     }
  94.  
  95. if (msfree != (Mstack *)NULL) {
  96.     tmpmat = vdevice.transmat;
  97.     vdevice.transmat = msfree;
  98.     msfree = msfree->back;
  99.     vdevice.transmat->back = tmpmat;
  100.     copymatrix(vdevice.transmat->m, tmpmat->m);
  101.     }
  102. else {
  103.     tmpmat = (Mstack *)vallocate(sizeof(Mstack));
  104.     tmpmat->back = vdevice.transmat;
  105.     copymatrix(tmpmat->m, vdevice.transmat->m);
  106.     vdevice.transmat = tmpmat;
  107.     }
  108. }
  109.  
  110. /* ------------------------------------------------------------------------ */
  111.  
  112. /*
  113.  * popmatrix
  114.  *
  115.  * Pop the top matrix from the stack.
  116.  *
  117.  */
  118. void popmatrix(void)
  119. {
  120. Token    *p;
  121. Mstack    *oldtop;
  122.  
  123. if (vdevice.inobject) {
  124.     p = newtokens(1);
  125.  
  126.     p->i = POPMATRIX;
  127.  
  128.     return;
  129.     }
  130.  
  131. if (vdevice.transmat->back == (Mstack *)NULL)
  132. verror("popmatrix: matrix stack empty");
  133. else {
  134.     oldtop = vdevice.transmat;
  135.     vdevice.transmat = vdevice.transmat->back;
  136.     oldtop->back = msfree;
  137.     msfree = oldtop;
  138.     }
  139.  
  140. vdevice.cpVvalid = 0;    /* may have changed mapping from world to device coords */
  141. }
  142.  
  143. /* ------------------------------------------------------------------------ */
  144.  
  145. /*
  146.  * loadmatrix
  147.  *
  148.  * Replace the top matrix on the stack
  149.  *
  150.  */
  151. void loadmatrix(Matrix mat)
  152. {
  153. register int    i;
  154. register float    *cm, *mp;
  155. Token        *p;
  156.  
  157. if (!vdevice.initialised)
  158. verror("loadmatrix: vogl not initialised");
  159.  
  160. if (vdevice.inobject) {
  161.     p = newtokens(17);
  162.  
  163.     p[0].i = LOADMATRIX;
  164.     cm = (float *)mat;
  165.     for (i = 0; i < 16; i++)
  166.     (++p)->f = *cm++;
  167.  
  168.     return;
  169.     }
  170.  
  171. cm = (float *)vdevice.transmat->m;
  172. mp = (float *)mat;
  173. for (i = 0; i < 16; i++)
  174. *cm++ = *mp++;
  175.  
  176. /*
  177.  * Save the untransformed matrix for the reverse mapping.
  178.  */
  179.  
  180. _mapmsave(mat);
  181.  
  182. vdevice.cpVvalid = 0;        /* may have changed mapping from world to device coords */
  183. }
  184.  
  185. /* ------------------------------------------------------------------------ */
  186.  
  187. /*
  188.  * mult4x4
  189.  *
  190.  *    multiply 4 x 4 matrices b and c assigning them into a. Readers are
  191.  * reminded that speed can be important here.
  192.  *
  193.  */
  194. void mult4x4(
  195.   register Matrix a,
  196.   register Matrix b,
  197.   register Matrix c)
  198. {
  199. a[0][0] = b[0][0] * c[0][0] + b[0][1] * c[1][0] + b[0][2] * c[2][0] + b[0][3] * c[3][0];
  200. a[0][1] = b[0][0] * c[0][1] + b[0][1] * c[1][1] + b[0][2] * c[2][1] + b[0][3] * c[3][1];
  201. a[0][2] = b[0][0] * c[0][2] + b[0][1] * c[1][2] + b[0][2] * c[2][2] + b[0][3] * c[3][2];
  202. a[0][3] = b[0][0] * c[0][3] + b[0][1] * c[1][3] + b[0][2] * c[2][3] + b[0][3] * c[3][3];
  203.  
  204. a[1][0] = b[1][0] * c[0][0] + b[1][1] * c[1][0] + b[1][2] * c[2][0] + b[1][3] * c[3][0];
  205. a[1][1] = b[1][0] * c[0][1] + b[1][1] * c[1][1] + b[1][2] * c[2][1] + b[1][3] * c[3][1];
  206. a[1][2] = b[1][0] * c[0][2] + b[1][1] * c[1][2] + b[1][2] * c[2][2] + b[1][3] * c[3][2];
  207. a[1][3] = b[1][0] * c[0][3] + b[1][1] * c[1][3] + b[1][2] * c[2][3] + b[1][3] * c[3][3];
  208.  
  209. a[2][0] = b[2][0] * c[0][0] + b[2][1] * c[1][0] + b[2][2] * c[2][0] + b[2][3] * c[3][0];
  210. a[2][1] = b[2][0] * c[0][1] + b[2][1] * c[1][1] + b[2][2] * c[2][1] + b[2][3] * c[3][1];
  211. a[2][2] = b[2][0] * c[0][2] + b[2][1] * c[1][2] + b[2][2] * c[2][2] + b[2][3] * c[3][2];
  212. a[2][3] = b[2][0] * c[0][3] + b[2][1] * c[1][3] + b[2][2] * c[2][3] + b[2][3] * c[3][3];
  213.  
  214. a[3][0] = b[3][0] * c[0][0] + b[3][1] * c[1][0] + b[3][2] * c[2][0] + b[3][3] * c[3][0];
  215. a[3][1] = b[3][0] * c[0][1] + b[3][1] * c[1][1] + b[3][2] * c[2][1] + b[3][3] * c[3][1];
  216. a[3][2] = b[3][0] * c[0][2] + b[3][1] * c[1][2] + b[3][2] * c[2][2] + b[3][3] * c[3][2];
  217. a[3][3] = b[3][0] * c[0][3] + b[3][1] * c[1][3] + b[3][2] * c[2][3] + b[3][3] * c[3][3];
  218. }
  219.  
  220. /* ------------------------------------------------------------------------ */
  221.  
  222. /*
  223.  * multmatrix
  224.  *
  225.  * Premultipy the top matrix on the stack by "mat"
  226.  *
  227.  */
  228. void multmatrix(Matrix mat)
  229. {
  230. Matrix    prod;
  231. float    *m;
  232. Token    *p;
  233. int    i;
  234.  
  235. if (vdevice.inobject) {
  236.     p = newtokens(17);
  237.  
  238.     p[0].i = MULTMATRIX;
  239.     m = (float *)mat;
  240.     for (i = 0; i < 16; i++)
  241.     (++p)->f = *m++;
  242.  
  243.     return;
  244.     }
  245.  
  246. mult4x4(prod, mat, vdevice.transmat->m);
  247. loadmatrix(prod);
  248. }
  249.  
  250. /* ------------------------------------------------------------------------ */
  251.  
  252. /*
  253.  * identmatrix
  254.  *
  255.  * Return a 4 x 4 identity matrix
  256.  *
  257.  */
  258. void identmatrix(Matrix a)
  259. {
  260. register float    *p;
  261.  
  262. for (p = (float *)a; p != (float *)a + 16; p++)
  263. *p = 0;
  264.  
  265. a[0][0] = a[1][1] = a[2][2] = a[3][3] = 1;
  266. }
  267.  
  268. /* ------------------------------------------------------------------------ */
  269.  
  270. /*
  271.  * multvector
  272.  *
  273.  * Multiply the vector a and the matrix b to form v. Need it to be snappy again.
  274.  * 
  275.  */
  276. void multvector(
  277.   register Vector v,
  278.   register Vector a,
  279.   register Matrix b)
  280. {
  281. v[0] = a[0] * b[0][0] + a[1] * b[1][0] + a[2] * b[2][0] + a[3] * b[3][0];
  282. v[1] = a[0] * b[0][1] + a[1] * b[1][1] + a[2] * b[2][1] + a[3] * b[3][1];
  283. v[2] = a[0] * b[0][2] + a[1] * b[1][2] + a[2] * b[2][2] + a[3] * b[3][2];
  284. v[3] = a[0] * b[0][3] + a[1] * b[1][3] + a[2] * b[2][3] + a[3] * b[3][3];
  285. }
  286.  
  287. /* ------------------------------------------------------------------------ */
  288.  
  289. /*
  290.  * premultvector
  291.  *
  292.  * PreMultiply the vector a and the matrix b to form v. 
  293.  * Need it to be snappy again.
  294.  * 
  295.  */
  296. void premultvector(
  297.   Vector v,
  298.   Vector a,
  299.   Matrix b)
  300. {
  301. v[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2] + a[3] * b[0][3];
  302. v[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2] + a[3] * b[1][3];
  303. v[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2] + a[3] * b[2][3];
  304. v[3] = a[0] * b[3][0] + a[1] * b[3][1] + a[2] * b[3][2] + a[3] * b[3][3];
  305. }
  306.  
  307. /* ------------------------------------------------------------------------ */
  308.  
  309. #ifdef DEBUG 
  310.  
  311. /*
  312.  * printmat
  313.  *
  314.  *    print s and then dump matrix m. Useful for debugging, you get
  315.  * sick of typing in the print loop otherwise.
  316.  */
  317. int printmat(
  318.   char *s,
  319.   Matrix m)
  320. {
  321. int    i, j;
  322.  
  323. printf("%s\n", s);
  324. for (i = 0; i < 4; i++) {
  325.     for (j = 0; j < 4; j++)
  326.     printf("%f ",m[i][j]);
  327.     printf("\n");
  328.     }
  329. }
  330.  
  331. /* ------------------------------------------------------------------------ */
  332.  
  333. int printvect(
  334.   char *s,
  335.   Vector v)
  336. {
  337. printf("%s %f %f %f %f\n", s, v[0], v[1], v[2], v[3]);
  338. }
  339.  
  340. /* ------------------------------------------------------------------------ */
  341.  
  342. #endif
  343.